<script setup lang="ts">
import type { render } from 'vue'
import parse from '@rojer/katex-mini'
import { onMounted, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'

// 定义 props 接收
const props = defineProps<{
  mathFormula: string
}>()
const nodes = parse(props.mathFormula, {
  delimiters: [
    { left: '$$', right: '$$', display: true },
    { left: '$', right: '$', display: false },
  ],
})
// 定义rich-text nodes的类型结构
type RichTextNode =
  | { type: 'text'; text: string }
  | { name: string; attrs: Record<string, string>; children?: RichTextNode[] }

function convert(htmlString: string): RichTextNode[] {
  // 移除字符串中的多余空格和换行（保留必要的空格）
  const cleanedHtml = htmlString.trim()
  const nodes: RichTextNode[] = []

  // 解析属性字符串（如 "src='xxx' style='yyy'" → {src: 'xxx', style: 'yyy'}）
  function parseAttrs(attrsStr: string): Record<string, string> {
    const attrs: Record<string, string> = {}
    if (!attrsStr) return attrs
    // 匹配属性（支持单引号、双引号、无引号）
    const attrReg = /([a-z-]+)\s*=\s*(?:'([^']*)'|"([^"]*)"|([^\s>]+))/gi
    let match: RegExpExecArray | null
    while ((match = attrReg.exec(attrsStr))) {
      const key = match[1]
      // 取第一个非空的属性值（单引号/双引号/无引号）
      const value = match[2] || match[3] || match[4] || ''
      attrs[key] = value
    }
    return attrs
  }

  // 处理LaTeX公式，将$...$转换为HTML
  function processLatex(text: string): RichTextNode[] {
    const nodes: RichTextNode[] = []
    const latexReg = /\$(.*?)\$/g
    let lastIndex = 0
    // 查找所有$...$模式的LaTeX公式
    let match: RegExpExecArray | null
    while ((match = latexReg.exec(text))) {
      const preText = text.slice(lastIndex, match.index)
      if (preText) {
        nodes.push({ type: 'text', text: preText })
      }
      const latex = match[1]
      try {
        // 使用katex-mini解析LaTeX为HTML
        const latexHtml = parse(latex)
        // 递归解析生成的HTML
        const latexNodes = parseHtml(latexHtml)
        nodes.push(...latexNodes)
      } catch (e) {
        // 解析失败时，保留原始文本
        nodes.push({ type: 'text', text: match[0] })
      }
      lastIndex = match.index + match[0].length
    }
    // 添加剩余文本
    if (lastIndex < text.length) {
      nodes.push({ type: 'text', text: text.slice(lastIndex) })
    }
    return nodes
  }

  // 递归解析HTML片段，生成nodes子节点
  function parseHtml(html: string): RichTextNode[] {
    const children: RichTextNode[] = []
    let index = 0
    const len = html.length

    while (index < len) {
      // 匹配文本内容（非标签部分）
      if (html[index] !== '<') {
        const textEnd = html.indexOf('<', index)
        const text = textEnd === -1 ? html.slice(index) : html.slice(index, textEnd)
        if (text.trim()) {
          // 处理可能包含LaTeX公式的文本
          const latexNodes = processLatex(text)
          children.push(...latexNodes)
        }
        index = textEnd === -1 ? len : textEnd
        continue
      }

      // 匹配开始标签（如 <p>、<img src="xxx" />）
      const startTagReg = /^<([a-z0-9]+)([^>]*?)(\/?)>/i
      const startMatch = html.slice(index).match(startTagReg)
      if (!startMatch) {
        // 不是有效的开始标签，可能是</p>等结束标签，作为文本处理
        const nextTagStart = html.indexOf('<', index + 1)
        const text = nextTagStart === -1 ? html.slice(index) : html.slice(index, nextTagStart)
        children.push({ type: 'text', text })
        index = nextTagStart === -1 ? len : nextTagStart
        continue
      }

      const tagName = startMatch[1].toLowerCase() // 标签名（转为小写）
      const attrsStr = startMatch[2] // 属性字符串
      const isSelfClose = startMatch[3] === '/' // 是否自闭合标签（如<img />）
      const attrs = parseAttrs(attrsStr) // 解析属性
      const tagLength = startMatch[0].length // 标签本身的长度
      index += tagLength

      // 自闭合标签（如<img />）：无children，直接添加节点
      if (isSelfClose) {
        children.push({
          name: tagName,
          attrs: attrs,
        })
        continue
      }

      // 非自闭合标签（如<p>）：需要找到对应的结束标签，解析内部内容作为children
      const endTag = `</${tagName}>`
      const endIndex = html.indexOf(endTag, index)
      if (endIndex === -1) {
        // 找不到结束标签，视为文本处理（容错）
        const text = html.slice(index)
        const latexNodes = processLatex(text)
        children.push(...latexNodes)
        break
      }

      // 提取标签内的内容（子内容）
      const innerHtml = html.slice(index, endIndex).trim()
      // 递归解析子内容，生成children
      const innerChildren = parseHtml(innerHtml)
      // 添加当前标签节点
      children.push({
        name: tagName,
        attrs: attrs,
        children: innerChildren,
      })

      // 移动索引到结束标签之后
      index = endIndex + endTag.length
    }

    return children
  }

  // 解析整个HTML字符串，生成顶层nodes
  console.log('cleanedHtml：', parseHtml(cleanedHtml))
  return parseHtml(cleanedHtml)
}
</script>

<template>
  <view class="body">
    <rich-text :nodes="nodes" class="rich-text" space="nbsp"></rich-text>
  </view>
</template>

<style lang="scss">
.body {
  display: flex;
  flex-flow: column nowrap;
  align-content: space-between;
  justify-items: flex-start;
}

.rich-text {
  text-align: left;
  width: auto;
  line-height: 30rpx;
}
</style>
